package com.springboot.oauth2.config;

import com.springboot.oauth2.config.custom.User;
import com.springboot.oauth2.entity.Login;
import com.springboot.oauth2.entity.Permission;
import com.springboot.oauth2.mapper.LoginMapper;
import com.springboot.oauth2.mapper.PermissionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Component
@Slf4j
public class UserDetailServiceImpl implements UserDetailsService {

  @Autowired private LoginMapper loginMapper;

  @Autowired private PermissionMapper permissionMapper;

  /**
   * 加载数据库中的认证的用户的信息：用户名，密码，用户的权限列表 该方法把username传入进来， 我们通过username查询用户的信息(密码，权限列表等)
   * 然后封装成User(实际上是UserDetails的实现类）进行返回
   *
   * @param username
   * @return: User
   * @date: 2021/12/23 19:50
   * @author: FuJilin
   */
  @Override
  public User loadUserByUsername(String username) throws UsernameNotFoundException {

    Login userFromDB = loginMapper.selectByUsername(username);
    if (null == userFromDB) {
      throw new RuntimeException("无效的用户");
    }

    // 模拟存储在数据库的用户的密码：123
    // String password = passwordEncoder.encode("123");
    String password = userFromDB.getPassword();

    // 查询用户的权限
    List<Permission> permission = permissionMapper.listByUserId(userFromDB.getId());

    // 用户的权限列表,暂时为空
    Collection<GrantedAuthority> authorities = new ArrayList<>();
    log.info("用户 \"{}\" 权限列表：", userFromDB.getName());
    permission.forEach(
        e -> {
          log.info("权限： \"{}\"    资源路径： \"{}\"", e.getSn(), e.getResource());
          authorities.add(new SimpleGrantedAuthority(e.getSn()));
        });
    log.info("用户 \"{}\" 权限加载完毕", userFromDB.getName());
    // 手动添加ROLE_权限，@Secured会用到
    authorities.add(new SimpleGrantedAuthority("ROLE_delete"));
    User user = new User(username, password, authorities);
    user.setUserId(userFromDB.getId());
    user.setPhone(userFromDB.getPhone());
    return user;
  }
}
